package com.imay.live.manager;

import android.Manifest;
import android.content.Context;
import android.graphics.SurfaceTexture;
import android.media.AudioManager;
import android.net.Uri;
import android.os.Environment;
import android.os.Handler;
import android.support.annotation.NonNull;
import android.text.TextUtils;
import android.util.Log;
import android.view.Surface;
import android.view.TextureView;
import android.view.ViewGroup;
import android.widget.RelativeLayout;

import com.danikula.videocache.HttpProxyCacheServer;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.ExoPlayerFactory;
import com.google.android.exoplayer2.PlaybackParameters;
import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.extractor.DefaultExtractorsFactory;
import com.google.android.exoplayer2.extractor.ExtractorsFactory;
import com.google.android.exoplayer2.source.ExtractorMediaSource;
import com.google.android.exoplayer2.source.LoopingMediaSource;
import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
import com.google.android.exoplayer2.trackselection.TrackSelector;
import com.google.android.exoplayer2.upstream.BandwidthMeter;
import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter;
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
import com.google.android.exoplayer2.util.Util;
import com.imay.live.helper.HWSupportList;
import com.imay.live.utils.FileUtil;
import com.imay.live.utils.PermissionUtil;
import com.imay.live.view.IMTextureView;
import com.tencent.rtmp.ITXLivePlayListener;
import com.tencent.rtmp.TXLiveConstants;
import com.tencent.rtmp.TXLivePlayConfig;
import com.tencent.rtmp.TXLivePlayer;
import com.tencent.rtmp.ui.TXCloudVideoView;

import java.io.File;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by chan on 2017/5/26 0026.
 */

public class PlayerManager {

    public final static int TXPLAYER = 0;

    public final static int EXOPLAYER = 1;

    private int videoType = EXOPLAYER;

    private Context mContext;

    /**
     * ================TX播放器设置部分===================
     */
    private static final int CACHE_STRATEGY_FAST = 1;  //极速
    private static final int CACHE_STRATEGY_SMOOTH = 2;  //流畅
    private static final int CACHE_STRATEGY_AUTO = 3;  //自动
    private static final float CACHE_TIME_FAST = 1.0f;
    private static final float CACHE_TIME_SMOOTH = 5.0f;

    private int mPlayType = TXLivePlayer.PLAY_TYPE_VOD_MP4;
    private int mCurrentRenderMode = TXLiveConstants.RENDER_MODE_FULL_FILL_SCREEN;  //填满屏幕
    private int mCurrentRenderRotation = TXLiveConstants.RENDER_ROTATION_PORTRAIT;

    private boolean mHWDecode = false;
    private TXLivePlayer mLivePlayer;
    private TXLivePlayConfig mPlayConfig;
    protected TXCloudVideoView mVideoView;
    private int mCacheStrategy = 0;

    /**
     * ===============EXO播放器设置部分=================
     */
    //默认显示比例
    public final static int SCREEN_TYPE_DEFAULT = 0;
    //16:9
    public final static int SCREEN_TYPE_16_9 = 1;
    //4:3
    public final static int SCREEN_TYPE_4_3 = 2;
    //全屏裁减显示
    public final static int SCREEN_TYPE_FULL = 4;
    //全屏拉伸显示，使用这个属性时，surface_container建议使用FrameLayout
    public final static int SCREEN_MATCH_FULL = -4;
    //显示比例类型
    private static int TYPE = SCREEN_TYPE_FULL;

    private SimpleExoPlayer mediaPlayer;
    private IMTextureView textureRenderView;
    private boolean cacheWithPlay = true;
    private File cachePath;
    private Map<String, Integer> url = new HashMap<>();

    /**
     * =====================
     */
    private static PlayerManager instance;
    private long seekto;

    public static synchronized PlayerManager getInstance() {
        if (instance == null) {
            instance = new PlayerManager();
        }
        return instance;
    }

    public PlayerManager() {

    }

    /**
     * 初始化播放器
     */
    public void initPlayer(Context content) {
        mContext = content;
        if (videoType == TXPLAYER) {
            initTXplayer(content);
        } else if (videoType == EXOPLAYER) {
            textureRenderView = new IMTextureView(content);
            cachePath = content.getExternalFilesDir(Environment.DIRECTORY_MOVIES);
            initEXOPlayer(content);
        }
    }

    private void initTXplayer(Context content) {
        mHWDecode = HWSupportList.isHWVideoEncodeSupport();
        mVideoView = new TXCloudVideoView(content);
        mLivePlayer = new TXLivePlayer(content);
        mPlayConfig = new TXLivePlayConfig();
        setCacheStrategy(CACHE_STRATEGY_SMOOTH);
        mLivePlayer.setPlayerView(mVideoView);
    }

    public void initEXOPlayer(Context context) {
        if (mediaPlayer == null) {
            // 1. Create a default TrackSelector
            BandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
            TrackSelector trackSelector =
                    new DefaultTrackSelector(bandwidthMeter);
            mediaPlayer =
                    ExoPlayerFactory.newSimpleInstance(context, trackSelector);
            // 3. Create the player
            mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
        }
    }

    /**
     * 缓存策略
     *
     * @param nCacheStrategy
     */
    private void setCacheStrategy(int nCacheStrategy) {
        if (mCacheStrategy == nCacheStrategy) {
            return;
        }
        mCacheStrategy = nCacheStrategy;
        switch (nCacheStrategy) {
            case CACHE_STRATEGY_FAST:
                mPlayConfig.setAutoAdjustCacheTime(true);
                mPlayConfig.setMaxAutoAdjustCacheTime(CACHE_TIME_FAST);
                mPlayConfig.setMinAutoAdjustCacheTime(CACHE_TIME_FAST);
                mLivePlayer.setConfig(mPlayConfig);
                break;
            case CACHE_STRATEGY_SMOOTH:
                mPlayConfig.setAutoAdjustCacheTime(false);
                mPlayConfig.setCacheTime(CACHE_TIME_SMOOTH);
                mLivePlayer.setConfig(mPlayConfig);
                break;
            case CACHE_STRATEGY_AUTO:
                mPlayConfig.setAutoAdjustCacheTime(true);
                mPlayConfig.setMaxAutoAdjustCacheTime(CACHE_TIME_SMOOTH);
                mPlayConfig.setMinAutoAdjustCacheTime(CACHE_TIME_FAST);
                mLivePlayer.setConfig(mPlayConfig);
                break;
            default:
                break;
        }
    }

    /**
     * 禁音
     *
     * @param b
     */
    public void setMute(boolean b) {
        if (videoType == TXPLAYER) {
            mLivePlayer.setMute(b);
        } else if (videoType == EXOPLAYER) {
            if (b) {
                mediaPlayer.setVolume(0);
            } else {
                mediaPlayer.setVolume(1);
            }
        }
    }

    /**
     * 停止播放
     */
    public void stop() {
        if (videoType == TXPLAYER) {
            mLivePlayer.setMute(true);
            mLivePlayer.setPlayListener(null);
            mLivePlayer.stopPlay(true);
            mVideoView.clearLastFrame(true);
            mVideoView.clearLog();

            removeTextureParentView();
        } else if (videoType == EXOPLAYER) {
            seekto = mediaPlayer.getCurrentPosition();
            mediaPlayer.stop();
            if (textureRenderView != null) {
                removeTextureParentView();
            }
        }
    }

    /**
     * 播放TX
     *
     * @param url
     * @param itxLivePlayListener
     */
    public int playTX(String url, ITXLivePlayListener itxLivePlayListener) {
        mVideoView.clearLastFrame(true);
        mVideoView.clearLog();
        mLivePlayer.stopPlay(true);

        mLivePlayer.setPlayListener(itxLivePlayListener);

        mLivePlayer.enableHardwareDecode(mHWDecode);
        mLivePlayer.setRenderRotation(mCurrentRenderRotation);
        mLivePlayer.setRenderMode(mCurrentRenderMode);
        mLivePlayer.setConfig(mPlayConfig);
        return mLivePlayer.startPlay(url, mPlayType);
    }

    /**
     * 播放exo
     *
     * @param url
     */
    public int playEXO(String url) {
        //mediaPlayer.release();
        initEXOPlayer(mContext);
        checkPermission();
        try {
            if (cacheWithPlay && url.startsWith("http") && !url.contains("127.0.0.1")) {
                HttpProxyCacheServer proxy = VideoManager.getProxy(mContext.getApplicationContext(), cachePath);
                url = proxy.getProxyUrl(url);
            }
        } catch (Exception e) {
            Log.e("VANKA", e.getMessage());
        }

        textureRenderView.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() {
            @Override
            public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
                mediaPlayer.setVideoTextureView(textureRenderView);
            }

            @Override
            public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
            }

            @Override
            public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
                mediaPlayer.clearVideoTextureView(textureRenderView);
                mediaPlayer.stop();
                //mediaPlayer.release();
                return true;
            }

            @Override
            public void onSurfaceTextureUpdated(SurfaceTexture surface) {
            }
        });
        DefaultBandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
        DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(mContext,
                Util.getUserAgent(mContext, mContext.getApplicationInfo().name), bandwidthMeter);
        ExtractorsFactory extractorsFactory = new DefaultExtractorsFactory();
        final MediaSource videoSource = new ExtractorMediaSource(Uri.parse(url),
                dataSourceFactory, extractorsFactory, null, null);
        mediaPlayer.setPlayWhenReady(true);
        mediaPlayer.setVideoListener(exoVideoListener);
        String orUrl = (String) textureRenderView.getTag();
        if (!TextUtils.isEmpty(orUrl) && orUrl.equals(url)) {
            mediaPlayer.seekTo(seekto);
        } else {
            textureRenderView.setTag(url);
            seekto = 0;
            mediaPlayer.seekTo(seekto);
        }
        mediaPlayer.prepare(videoSource);
        mediaPlayer.setVideoScalingMode(C.VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING);
        mediaPlayer.addListener(new ExoPlayer.EventListener() {
            @Override
            public void onLoadingChanged(boolean isLoading) {
            }

            @Override
            public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
                switch (playbackState) {
                    case ExoPlayer.STATE_BUFFERING:
                        break;
                    case ExoPlayer.STATE_ENDED:
                        mediaPlayer.stop();
                        mediaPlayer.prepare(videoSource);
                        break;
                    case ExoPlayer.STATE_IDLE:
                        break;
                    case ExoPlayer.STATE_READY:
                        break;
                    default:
                        break;
                }

            }

            @Override
            public void onTimelineChanged(Timeline timeline, Object manifest) {
            }

            @Override
            public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {
            }

            @Override
            public void onPlayerError(ExoPlaybackException error) {
            }

            @Override
            public void onPositionDiscontinuity() {
            }

            @Override
            public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) {
            }
        });

        return 0;
    }

    public void replayer(String url) {
        if (videoType == TXPLAYER) {
            mVideoView.clearLastFrame(true);
            mVideoView.clearLog();
            mLivePlayer.stopPlay(true);
            mLivePlayer.startPlay(url, mPlayType);
        }
    }


    /**
     * 设置播放器的位置
     *
     * @param textureParentView
     */
    public void setTextureParentView(RelativeLayout textureParentView) {
        if (videoType == TXPLAYER) {
            if (mVideoView != null) {
                removeTextureParentView();
                textureParentView.addView(mVideoView, 1, new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
            }
        } else if (videoType == EXOPLAYER) {
            if (textureRenderView != null) {
                removeTextureParentView();
                textureParentView.addView(textureRenderView, 1, new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
            }
        }
    }

    /**
     * 移除播放器的父布局
     */
    public void removeTextureParentView() {
        if (videoType == TXPLAYER) {
            ViewGroup parentView = (ViewGroup) mVideoView.getParent();
            if (parentView != null) {
                parentView.removeView(mVideoView);
            }
        } else if (videoType == EXOPLAYER) {
            ViewGroup parentView = (ViewGroup) textureRenderView.getParent();
            if (parentView != null) {
                parentView.removeView(textureRenderView);
            }
        }
    }

    /**
     * 暂停播放
     */
    public void pause() {
        if (videoType == TXPLAYER) {
            mLivePlayer.pause();
        } else if (videoType == EXOPLAYER) {
            mediaPlayer.setPlayWhenReady(false);
        }
    }

    /**
     * 继续播放
     */
    public void resume() {
        if (videoType == TXPLAYER) {
            mLivePlayer.resume();
        } else if (videoType == EXOPLAYER) {
            mediaPlayer.setPlayWhenReady(true);
        }
    }

    /**
     * exo视频尺寸监听
     */
    private SimpleExoPlayer.VideoListener exoVideoListener = new SimpleExoPlayer.VideoListener() {
        @Override
        public void onVideoSizeChanged(int width, int height, int unappliedRotationDegrees, float pixelWidthHeightRatio) {
            textureRenderView.transformVideo(width, height);
            textureRenderView.requestLayout();
        }

        @Override
        public void onRenderedFirstFrame() {

        }
    };

    /**
     * 释放
     */
    public void release() {
        if (videoType == TXPLAYER) {
            mVideoView.clearLastFrame(true);
            mVideoView.clearLog();
            mVideoView.onDestroy();
            mLivePlayer.setPlayListener(null);
            mLivePlayer.stopPlay(true);
            mLivePlayer = null;
            mVideoView = null;
        } else if (videoType == EXOPLAYER) {
            mediaPlayer.stop();
            mediaPlayer.clearVideoListener(exoVideoListener);
            mediaPlayer.clearVideoTextureView(textureRenderView);
            mediaPlayer.release();
//            VideoManager.instance().releaseMediaPlayer();
            mediaPlayer = null;
            textureRenderView = null;
        }
    }

    /**
     * 检查读取权限
     */
    private void checkPermission() {
        if (!PermissionUtil.selfPermissionGranted(mContext, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
            cacheWithPlay = false;
        }
        if (!PermissionUtil.selfPermissionGranted(mContext, Manifest.permission.READ_EXTERNAL_STORAGE)) {
            cacheWithPlay = false;
        }
        if (!PermissionUtil.selfPermissionGranted(mContext, Manifest.permission.INTERNET)) {
            cacheWithPlay = false;
        }
    }

    public static int getShowType() {
        return TYPE;
    }

    /**
     * 设置显示比例,注意，这是全局生效的
     */
    public static void setShowType(int type) {
        TYPE = type;
    }
}
